package com.cloud.utils;

import org.apache.commons.lang3.ObjectUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

import java.awt.*;
import java.io.File;
import java.io.InputStream;

/**
 * 创建图表工具类
 *
 * @author yzj
 */
public class FreeChartUtils {

    /**
     * 创建饼图
     *
     * @param dataSet
     * @param file
     * @param title
     */
    public void createPieChart(DefaultPieDataset dataSet, File file, String title) {
        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createPieChart(title, dataSet, true, true, true);
            // 设置图表样式
            setUpRoundChart(chart);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsPNG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置环形图
     *
     * @param dataset
     * @param file
     * @param title
     */
    public void createRingChart(DefaultPieDataset dataset, File file, String title) {
        try {
            JFreeChart chart = ChartFactory.createRingChart(title, dataset, false, false, true);
            // 设置图表样式
            setUpRoundChart(chart);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置3D饼图
     *
     * @param dataset
     * @param file
     * @param title
     */
    public void create3DPieChart(DefaultPieDataset dataset, File file, String title) {
        try {
            JFreeChart chart = ChartFactory.createPieChart3D(title, dataset, false, false, true);
            // 设置图表样式
            setUpRoundChart(chart);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置圆形图表样式
     *
     * @param chart
     */
    public void setUpRoundChart(JFreeChart chart) {
        // 如果不使用Font,中文将显示不出来
        Font font = this.getFont(Font.BOLD, 12);
        // 设置图片标题的字体
        chart.getTitle().setFont(font);
        // 得到图块,准备设置标签的字体
        PiePlot plot = (PiePlot) chart.getPlot();
        // 设置标签字体
        plot.setLabelFont(font);
        plot.setStartAngle(3.14f / 2f);
        // 设置plot的前景色透明度
        plot.setForegroundAlpha(0.7f);
        // 设置plot的背景色透明度
        plot.setBackgroundAlpha(0.0f);
        // 设置标签生成器(默认{0}) {0}:key {1}:value {2}:百分比 {3}:sum
        plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}占{2}"));
    }


    /**
     * 创建条形图
     *
     * @param title
     * @param xAxis     X轴标签
     * @param yAxis     Y轴标签
     * @param file
     * @param dataSet
     * @param direction 条形图方向 PlotOrientation.HORIZONTAL, PlotOrientation.VERTICAL
     */
    public void createBarChart(String title, String xAxis, String yAxis, File file, CategoryDataset dataSet, PlotOrientation direction) {
        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createBarChart(title, xAxis, yAxis, dataSet, direction, true, true, true);
            // 设置图表样式
            setUpBarChart(chart);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建堆积条形图
     *
     * @param title
     * @param xAxis     X轴标签
     * @param yAxis     Y轴标签
     * @param file
     * @param dataSet
     * @param direction 条形图方向 PlotOrientation.HORIZONTAL, PlotOrientation.VERTICAL
     */
    public void createHeapBarChart(String title, String xAxis, String yAxis, File file, CategoryDataset dataSet, PlotOrientation direction) {
        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createStackedBarChart(title, xAxis, yAxis, dataSet, direction, true, true, true);
            // 设置图表样式
            setUpBarChart(chart);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建折线图
     *
     * @param title
     * @param xAxis     X轴标签
     * @param yAxis     Y轴标签
     * @param file
     * @param dataSet
     * @param direction 条形图方向 PlotOrientation.HORIZONTAL, PlotOrientation.VERTICAL
     */
    public void createLineChart(String title, String xAxis, String yAxis, File file, CategoryDataset dataSet, PlotOrientation direction) {
        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createLineChart(title, xAxis, yAxis, dataSet, direction, true, true, true);
            // 设置图表样式
            setUpBarChart(chart);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置柱形/折线图表样式
     *
     * @param chart
     */
    private void setUpBarChart(JFreeChart chart) {
        // 如果不使用Font,中文将显示不出来
        Font font = getFont(Font.BOLD, 12);
        // 设置图片标题的字体
        chart.getTitle().setFont(font);
        chart.getLegend().setItemFont(font);
        // 得到图块,准备设置标签的字体
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        // 设置plot的前景色透明度
        plot.setForegroundAlpha(0.7f);
        // 设置plot的背景色透明度
        plot.setBackgroundAlpha(0.0f);
        // 设置标签生成器
        ValueAxis rangeAxis = plot.getRangeAxis();
        CategoryAxis domainAxis = plot.getDomainAxis();
        rangeAxis.setLabelFont(font);
        rangeAxis.setTickLabelFont(font);
        domainAxis.setLabelFont(font);
        domainAxis.setTickLabelFont(font);
        domainAxis.setMaximumCategoryLabelLines(10);
        domainAxis.setMaximumCategoryLabelWidthRatio(0.5f);
    }

    /**
     * 获取字体样式
     *
     * @param style
     * @param size
     * @return
     */
    private Font getFont(int style, int size) {
        Font defFont = new Font("宋体", style, size);
        try {
            // 获得字体路径,此处为宋体
            InputStream resource = this.getClass().getResourceAsStream("/simsun.ttc");
            if (ObjectUtils.isEmpty(resource)) {
                return defFont;
            }
            Font newFont = Font.createFont(Font.TRUETYPE_FONT, resource);
            newFont = newFont.deriveFont(style, size);
            return newFont;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defFont;
    }

}
